home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * CagdCSrf.c - Construct a surface using a set of curves. *
- *******************************************************************************
- * Written by Gershon Elber, Sep. 91. *
- ******************************************************************************/
-
- #include "cagd_loc.h"
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Constructs a surface using a set of curves. Curves are made to be M
- * compatible and then each is substituted into the new surface's mesh as a M
- * row. M
- * If the OtherOrder is less than the number of curves, number of curves is M
- * used. M
- * A knot vector is formed with uniform open end for the other direction, M
- * so it interpolates the first and last curves. M
- * Note, however, that only the first and the last curves are interpolated M
- * if OtherOrder is greater than 2. M
- * *
- * PARAMETERS: M
- * CrvList: List of curves to consturct a surface with. M
- * OtherOrder: Other order of surface. M
- * *
- * RETURN VALUE: M
- * CagdSrfStruct *: Constructed surface from curves. M
- * *
- * KEYWORDS: M
- * CagdSrfFromCrvs, surface constructors M
- *****************************************************************************/
- CagdSrfStruct *CagdSrfFromCrvs(CagdCrvStruct *CrvList, int OtherOrder)
- {
- CagdBType IsNotRational;
- int i, j, NumCrvs, UOrder, VOrder, MaxCoord, Length;
- CagdRType **SrfPoints;
- CagdCrvStruct *Crv, **CrvVec;
- CagdSrfStruct *Srf;
-
- /* Find out how many curves we have and put them in a linear vector. */
- /* Note the vector have a COPY of the curves so we can modify them. */
- for (NumCrvs = 0, Crv = CrvList;
- Crv != NULL;
- NumCrvs++, Crv = Crv -> Pnext);
- CrvVec = (CagdCrvStruct **) IritMalloc(sizeof(CagdCrvStruct *) * NumCrvs);
- for (i = 0, Crv = CrvList;
- i < NumCrvs;
- i++, Crv = Crv -> Pnext)
- CrvVec[i] = CagdCrvCopy(Crv);
-
- /* Traverse vector in a O(n^2) fashion and make all curves compatible. */
- for (i = 0; i < NumCrvs - 1; i++)
- for (j = i + 1; j < NumCrvs; j++)
- CagdMakeCrvsCompatible(&CrvVec[i], &CrvVec[j], TRUE, TRUE);
-
- /* Construct the surface. All required information is now available. */
- UOrder = CrvVec[0] -> Order;
- VOrder = MIN(NumCrvs, OtherOrder);
- if (NumCrvs == VOrder && CrvVec[0] -> GType == CAGD_CBEZIER_TYPE) {
- /* Allocate a bezier surface. */
- Srf = BzrSrfNew(CrvVec[0] -> Length, NumCrvs, CrvVec[0] -> PType);
- }
- else {
- /* Allocate a bspline surface. */
- Srf = BspPeriodicSrfNew(CrvVec[0] -> Length, NumCrvs, UOrder, VOrder,
- CrvVec[0] -> Periodic, FALSE,
- CrvVec[0] -> PType);
- IritFree((VoidPtr) Srf -> UKnotVector);
- Srf -> UKnotVector = BspKnotCopy(CrvVec[0] -> KnotVector,
- CAGD_CRV_PT_LST_LEN(CrvVec[0]) +
- UOrder);
- BspKnotUniformOpen(NumCrvs, VOrder, Srf -> VKnotVector);
- }
-
- /* Substitute each curve as a row into the surface mesh and delete it. */
- SrfPoints = Srf -> Points;
- i = 0;
- MaxCoord = CAGD_NUM_OF_PT_COORD(CrvVec[0] -> PType),
- IsNotRational = !CAGD_IS_RATIONAL_CRV(CrvVec[0]);
- Length = CrvVec[0] -> Length;
-
- for (j = 0; j < NumCrvs; j++) {
- int k;
- CagdRType
- **CrvPoints = CrvVec[j] -> Points;
-
- for (k = IsNotRational; k <= MaxCoord; k++)
- CAGD_GEN_COPY(&SrfPoints[k][i], CrvPoints[k],
- sizeof(CagdRType) * Length);
-
- CagdCrvFree(CrvVec[j]);
- i += Length;
- }
-
- IritFree((VoidPtr) CrvVec);
-
- return Srf;
- }
-